package com.koron.common.core.util.weixin;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.koron.common.core.util.weixin.bean.WxProgramProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName WxMessageUtil
 * @description
 * @Author zhouj
 * @Date 2021/5/10 9:05
 */
@Slf4j
@Component
public class WxProgramMessageUtil {

    private static HttpClient httpClient = new HttpClient();

    private static ConcurrentHashMap<String, ConcurrentHashMap<String, Object>> cond = new ConcurrentHashMap<>();

    @Autowired
    private WxProgramProperties wxProgramProperties;

    private String access_token;

    //默认7200  即2小时
    private static int EXPIRE_TIME = 7000;

    public String getAccessTokenCache() {

        int currentSec = getSecondTimestamp(new Date());

        //将获取到的access_token 进行缓存
        Map<String, Object> map = cond.get("access_token");
        if (map != null) {
            //校验是否过期
            int time1 = (Integer)map.get(access_token);
            if (currentSec - time1 > 7000) {
                String accessToken = getAccessToken();
                map.clear();
                map.put(accessToken, currentSec);
                this.access_token = accessToken;
            }
        } else {
            String accessToken = getAccessToken();
            ConcurrentHashMap<String, Object> map1 = new ConcurrentHashMap<>();
            map1.put(accessToken, currentSec);
            cond.put("access_token", map1);
            this.access_token = accessToken;
        }

        return this.access_token;
    }

    public String getAccessToken() {

        String appId = wxProgramProperties.getAppId();
        String appSecret = wxProgramProperties.getSecret();
        String result = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret);
        log.info("appId = {}, appSecret = {}, token = {}", appId, appSecret, result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        return jsonObject.getString("access_token");

    }


    public String send(Map<String, Object> map) {
        JSONObject body = new JSONObject();

        body.put("touser", wxProgramProperties.getTouser());
        body.put("template_id", wxProgramProperties.getTemplateId());
        JSONObject json = new JSONObject();

        Set<Map.Entry<String, Object>> entries = map.entrySet();
        Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            final String key = next.getKey();
            final String value = (String) next.getValue();
            json.put(key, getJsonObject(value));
        }

        body.put("data", json);
        log.info(body.toJSONString());

        //发送前  获取操作凭证（2小时过期）
        String accessToken = getAccessTokenCache();
        String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken, body.toString());
        log.info(post);
        return "ok";
    }

    public JSONObject getJsonObject(String value) {
        return getJsonObject(null, value);
    }

    //根据value值获取jsonobject  key默认为"value"
    public JSONObject getJsonObject(String key, String value) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(key == null ? "value" : key, value);
        return jsonObject;
    }

    //获取时间的秒时间戳
    public static int getSecondTimestamp(Date date) {
        if (null == date) {
            return 0;
        }
        String timestamp = String.valueOf(date.getTime());
        int length = timestamp.length();
        if (length > 3) {
            return Integer.parseInt(timestamp.substring(0, length - 3));
        } else {
            return 0;
        }
    }


}
